﻿using Google.Protobuf;
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;


namespace WebApplication_GrpcServer.Services
{
    public class LocalStudentsService : StudentServices.StudentServicesBase
    {
        private readonly ILogger<LocalStudentsService> _logger;

        public LocalStudentsService(ILogger<LocalStudentsService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 一元方法
        /// </summary>
        /// <param name="request"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async override Task<StudentResopnse> GetStudentByNo(StudentNoRequest request, ServerCallContext context)
        {
            if (!CheckMetadataValid(context))
            {
                _logger.LogWarning($"用户名userName验证失败！");
                return await Task.FromResult(new StudentResopnse { CurResopnseStudent = null });
            }
            Student result = FakeTestDataBase.FakeDataBase.FirstOrDefault(s => s.No == request.No);
            _logger.LogInformation($"返回请求学生信息：{result}");
            return await Task.FromResult(new StudentResopnse { CurResopnseStudent = result });
        }

        public async override Task<StudentResopnse> SaveStudent(StudentRequest request, ServerCallContext context)
        {
            CheckMetadataValid(context);

            bool isExis = FakeTestDataBase.FakeDataBase.Exists(s => s.No == request.CurRequestStudent.No);
            if (isExis)
            {
                _logger.LogWarning($"数据库中已经存在学生编号：{request.CurRequestStudent.No}");
                return await Task.FromResult(new StudentResopnse() { CurResopnseStudent = null });
            }
            else
            {
                lock (this)
                {
                    FakeTestDataBase.FakeDataBase.Add(request.CurRequestStudent);
                }
                _logger.LogInformation($"添加数据成功：{request.CurRequestStudent}");
                return await Task.FromResult(new StudentResopnse { CurResopnseStudent = request.CurRequestStudent });
            }
        }

        protected bool CheckMetadataValid(ServerCallContext context)
        {
            bool valid = false;
            Metadata entries = context.RequestHeaders;

            //元数据会把传入的参数 默认都转化成小写。 所以在比较时候可以比较lower

            foreach (var kvp in entries)
            {
                _logger.LogInformation($"Metadata:{kvp.Key}:{kvp.Value}");
                //if (kvp.Key == "userName" && kvp.Value == "admin")
                if (string.Compare(kvp.Key, "userName", true) == 0 && string.Compare(kvp.Value, "admin", true) == 0)
                {
                    valid = true;
                    break;
                }
            }
            return valid;
        }


        //服务器流式方式
        public async override Task GetAllStudents
            (StudentAllRequest request, IServerStreamWriter<StudentResopnse> responseStream, ServerCallContext context)
        {

            foreach (var s in FakeTestDataBase.FakeDataBase)
            {
                await responseStream.WriteAsync(new StudentResopnse { CurResopnseStudent = s });
                await Task.Delay(10);
            }
        }


        //双向流方式处理
        public async override Task SaveMutilSudents(IAsyncStreamReader<StudentRequest> requestStream, IServerStreamWriter<StudentMutilResponse> responseStream, ServerCallContext context)
        {
            Task readTask = Task.Run(async () =>
            {
                await foreach (var message in requestStream.ReadAllAsync())
                {
                    message.CurRequestStudent.Id = FakeTestDataBase.FakeDataBase.Count + 1;
                    FakeTestDataBase.FakeDataBase.Add(message.CurRequestStudent);
                    //返回添加的学生信息
                    await responseStream.WriteAsync(new StudentMutilResponse { StudentInfo = message.CurRequestStudent });
                    _logger.LogInformation($"添加接收 到的学生信息：{message.CurRequestStudent}");
                }
            });

            readTask.Wait();
            await responseStream.WriteAsync(new StudentMutilResponse { IsOk = true });
            _logger.LogInformation($"返回请求结果！");
           // await Task.Delay(100, context.CancellationToken);

        }


        //客户端流式处理
        public async override Task<StudentResopnse> SetHeadPhoto(IAsyncStreamReader<StudentPhototRequest> requestStream, ServerCallContext context)
        {
            var UnVaildResult = new StudentResopnse() { CurResopnseStudent = null };

            //效验用户有效性
            if (!CheckMetadataValid(context))
            {
                _logger.LogWarning($"用户名验证错误！");
                return await Task.FromResult(UnVaildResult);
            }

            if (!int.TryParse(context.RequestHeaders.GetValue("no"), out int no))
            {
                _logger.LogWarning($"no found no info!");
                return await Task.FromResult(UnVaildResult);
            }
            if (!FakeTestDataBase.FakeDataBase.Exists(s => s.No == no))
            {
                _logger.LogWarning($"不存在no={no}信息");
                return await Task.FromResult(UnVaildResult);
            }

            Student destStudent = FakeTestDataBase.FakeDataBase.FirstOrDefault(s1 => s1.No == no);

            List<byte> photoDataLs = new List<byte>();
            while (await requestStream.MoveNext())
            {
                photoDataLs.AddRange(requestStream.Current.Data);
                _logger.LogInformation($"接收到图片数据包长度：{requestStream.Current.Data.Length} bytes");
            }

            destStudent.HeadPhoto = ByteString.CopyFrom(photoDataLs.ToArray());
            _logger.LogInformation($"图片数据包长度共：{photoDataLs.Count} bytes");
            return await Task.FromResult(new StudentResopnse() { CurResopnseStudent = destStudent });
        }
    }
}
